/*******************************************************************************
 * Copyright (c) 2013 Prometheus Consulting
 *
 *     Licensed under the Apache License, Version 2.0 (the "License"); you may
 *     not use this file except in compliance with the License. You may obtain
 *     a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *     WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *     License for the specific language governing permissions and limitations
 *     under the License.
 *******************************************************************************/
package nz.co.senanque.pizzaorder;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import nz.co.senanque.pizzaorder.catalogue.CatalogueFactory;
import nz.co.senanque.pizzaorder.catalogue.CatalogueItem;
import nz.co.senanque.pizzaorder.instances.Customer;
import nz.co.senanque.pizzaorder.instances.Order;
import nz.co.senanque.pizzaorder.instances.OrderItem;
import nz.co.senanque.rules.RulesPlugin;
import nz.co.senanque.vaadinsupport.LabelProperty;
import nz.co.senanque.vaadinsupport.MaduraPropertyWrapper;
import nz.co.senanque.vaadinsupport.application.MaduraSessionManager;
import nz.co.senanque.vaadinsupport.permissionmanager.PermissionManager;
import nz.co.senanque.vaadinsupport.viewmanager.HelpLayout;
import nz.co.senanque.vaadinsupport.viewmanager.ViewManaged;
import nz.co.senanque.vaadinsupport.viewmanager.ViewManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;

import com.vaadin.Application;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.service.ApplicationContext;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;

public class MainLayout extends CustomComponent implements InitializingBean, ViewManaged, MessageSourceAware {

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private VerticalLayout verticalLayout_1;
	@AutoGenerated
	private HorizontalLayout horizontalLayout_1;
	@AutoGenerated
	private VerticalLayout verticalLayout_3;
	@AutoGenerated
	private CustomerLayout customerLayout_1;
	@AutoGenerated
	private ShoppingCartLayout shoppingCartLayout_1;
	@AutoGenerated
	private ProductLayout productLayout_1;
	@AutoGenerated
	private HomeLayout homeLayout_1;
	@AutoGenerated
	private Tree productcatalogue;
	@AutoGenerated
	private HorizontalLayout horizontalLayout_2;
	@AutoGenerated
	private HorizontalLayout horizontalLayout_3;
	@AutoGenerated
	private Label label_1;
	@AutoGenerated
	private Button bmiButton;
	@AutoGenerated
	private Button helpButton;
	@AutoGenerated
	private Button logoutButton;
	@AutoGenerated
	private Button checkoutButton;
	@AutoGenerated
	private Button customerButton;
	@AutoGenerated
	private Button homeButton;
	@AutoGenerated
	private Embedded embedded_1;

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */
	private Order m_order;
	@Autowired private CatalogueFactory m_catalogueFactory;
	@Autowired PermissionManager m_permissionManager;
	@Autowired RulesPlugin m_rulesPlugin;
	private MessageSourceAccessor m_messageSourceAccessor;
	private ViewManager m_viewManager;
	@Autowired private MaduraSessionManager m_maduraSessionManager;
	public MaduraSessionManager getMaduraSessionManager() {
		return m_maduraSessionManager;
	}

	public void setMaduraSessionManager(MaduraSessionManager maduraSessionManager) {
		m_maduraSessionManager = maduraSessionManager;
	}

    private final Logger logger = LoggerFactory.getLogger(MainLayout.class);

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":false,"snapToObject":false,"movingGuides":false,"snappingDistance":10} */
	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 * @param catalogue2 
	 */
	public MainLayout() {
	}

	public void afterPropertiesSet() throws Exception {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		homeLayout_1.setMessageSourceAccessor(m_messageSourceAccessor);
		productLayout_1.setOwner(this);
		getMaduraSessionManager().register(label_1);
//		final Window window = this.getWindow();
		
		productcatalogue.addListener(new ItemClickListener(){

			@Override
			public void itemClick(ItemClickEvent event) {
				Object itemId = event.getItemId();
				if (itemId instanceof CatalogueItem)
				{
					CatalogueItem catalogueItem = (CatalogueItem)itemId;
					OrderItem orderItem=null;
					try {
						orderItem = (OrderItem)catalogueItem.getType().newInstance();
						orderItem.setName(catalogueItem.getName());
					} catch (Exception e) {
						e.printStackTrace();
					}
					m_order.getOrderItems().add(orderItem);
					getMaduraSessionManager().updateOtherFields(null);
					switchtoProduct(orderItem);
				}
			}});
		homeButton.setCaption(m_messageSourceAccessor.getMessage("home"));
		homeButton.addListener(new ClickListener(){

			@Override
			public void buttonClick(ClickEvent event) {
				switchtoHome();
			}});
		checkoutButton.setCaption(m_messageSourceAccessor.getMessage("checkout"));
		checkoutButton.addListener(new ClickListener(){

			@Override
			public void buttonClick(ClickEvent event) {
				switchtoShoppingCart();
			}});
		helpButton.setCaption(m_messageSourceAccessor.getMessage("help"));
		helpButton.addListener(new ClickListener(){

			@Override
			public void buttonClick(ClickEvent event) {
				getViewManager().pushScreen(HelpLayout.class.getName());
			}});
		bmiButton.setCaption(m_messageSourceAccessor.getMessage("bmi"));
		bmiButton.addListener(new ClickListener(){

			@Override
			public void buttonClick(ClickEvent event) {
				OneFieldWindow.init(getRulesPlugin(), m_order.getCustomer(), "bmi", getWindow(),m_maduraSessionManager);
			}});
		
		customerButton.setCaption(m_messageSourceAccessor.getMessage("customer"));
		customerButton.addListener(new ClickListener(){

			@Override
			public void buttonClick(ClickEvent event) {
				getViewManager().pushScreen(CustomerLayout.class.getName());
			}});
		logoutButton.setCaption(m_messageSourceAccessor.getMessage("logout"));
		logoutButton.addListener(new ClickListener(){

			@Override
			public void buttonClick(ClickEvent event) {
				getViewManager().logout();
			}});
		
		// When we complete a log in this event intialises the order
		addListener(new RepaintRequestListener(){

			public void repaintRequested(RepaintRequestEvent event) {
				initializeOrder();
				
			}});

	}

	private String getThemedResource()
	{
		Application application = getApplication();  
		ApplicationContext applicationContext = application.getContext();
		File basepath = applicationContext.getBaseDirectory();
		ThemeResource themeResource = new ThemeResource("login.html");
	    String theme = getApplication().getTheme();
	    String loginLocation = "/VAADIN/themes/"+theme+"/login.html";
	    InputStream is = this.getClass().getResourceAsStream(loginLocation);
	    if (is == null)
	    {
	    	throw new RuntimeException("Failed to find resource");
	    }
	    StringBuilder sb = new StringBuilder();
	    while (true)
	    {
	        byte[] bytes = new byte[1000];
	        int i=0;
	        try {
	            i = is.read(bytes);
	        } catch (IOException e) {
	            throw new RuntimeException("Failed to open login.html");
	        }
	        if (i == -1)
	        {
	            break;
	        }
	        sb.append(new String(bytes,0,i));
	    }
	    return sb.toString();
	}

	public void switchtoHome()
	{
		shoppingCartLayout_1.setVisible(false);
		productLayout_1.setVisible(false);
		homeLayout_1.setVisible(true);
		homeLayout_1.setEnabled(true);		
		customerLayout_1.setVisible(false);
		customerLayout_1.setEnabled(false);		
        productcatalogue.setEnabled(true);
        homeButton.setEnabled(true);
        checkoutButton.setEnabled(true);
        customerButton.setEnabled(true);
	}
	public void switchtoCustomer()
	{
		shoppingCartLayout_1.setVisible(false);
		productLayout_1.setVisible(false);
		homeLayout_1.setVisible(false);
		homeLayout_1.setEnabled(false);		
		customerLayout_1.setVisible(true);
		customerLayout_1.setEnabled(true);		
        productcatalogue.setEnabled(true);
        homeButton.setEnabled(true);
        checkoutButton.setEnabled(true);
        customerButton.setEnabled(false);
	}
	public void switchtoShoppingCart()
	{
		shoppingCartLayout_1.setVisible(true);
		productLayout_1.setVisible(false);
		homeLayout_1.setVisible(false);
		shoppingCartLayout_1.setEnabled(true);		
        productcatalogue.setEnabled(true);
        homeButton.setEnabled(true);
        checkoutButton.setEnabled(false);
		BeanItemContainer<OrderItem> indexed = new BeanItemContainer<OrderItem>(OrderItem.class, m_order.getOrderItems());
        shoppingCartLayout_1.setOrderItems(indexed,m_order);
        customerButton.setEnabled(true);
	}
	public void switchtoProduct(OrderItem orderItem)
	{
        productcatalogue.setEnabled(false);
        homeButton.setEnabled(false);
        checkoutButton.setEnabled(false);
		productLayout_1.setProduct(orderItem);
		homeLayout_1.setVisible(false);
		shoppingCartLayout_1.setVisible(false);
		productLayout_1.setVisible(true);
		productLayout_1.setEnabled(true);
		productLayout_1.setNewMode(true);
        customerButton.setEnabled(true);
	}
	public void cancel(OrderItem orderItem )
	{
		m_order.getOrderItems().remove(orderItem);
		getMaduraSessionManager().updateOtherFields(null);
	}
	public void initializeOrder() {
		if (m_order != null)
		{
			// only do this once.
			return;
		}
		m_order = new Order();
        Customer customer = new Customer();
        m_order.setCustomer(customer);
        MaduraSessionManager maduraSessionManager = getMaduraSessionManager();
        maduraSessionManager.getValidationSession().bind(m_order);
        CustomerLayout cl = (CustomerLayout)getViewManager().get(CustomerLayout.class.getName());
        cl.bind(m_order.getCustomer());

		MaduraPropertyWrapper property = maduraSessionManager.getMaduraPropertyWrapper(m_order, "shoppingCartStatus");
		maduraSessionManager.bind(label_1, new LabelProperty(property));
		try {
			productcatalogue.setContainerDataSource(getCatalogueFactory().getObject());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		productcatalogue.expandItemsRecursively(productcatalogue.rootItemIds());
	}

	public void setCatalogueFactory(CatalogueFactory catalogueFactory) {
		m_catalogueFactory = catalogueFactory;
	}
	public CatalogueFactory getCatalogueFactory() {
		return m_catalogueFactory;
	}

	public PermissionManager getPermissionManager() {
		return m_permissionManager;
	}

	public void setPermissionManager(PermissionManager permissionManager) {
		m_permissionManager = permissionManager;
	}
	public void setMessageSource(MessageSource messageSource) {
		m_messageSourceAccessor = new MessageSourceAccessor(messageSource);		
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// verticalLayout_1
		verticalLayout_1 = buildVerticalLayout_1();
		mainLayout.addComponent(verticalLayout_1);
		
		return mainLayout;
	}

	@AutoGenerated
	private VerticalLayout buildVerticalLayout_1() {
		// common part: create layout
		verticalLayout_1 = new VerticalLayout();
		verticalLayout_1.setImmediate(false);
		verticalLayout_1.setWidth("-1px");
		verticalLayout_1.setHeight("-1px");
		verticalLayout_1.setMargin(false);
		
		// horizontalLayout_2
		horizontalLayout_2 = buildHorizontalLayout_2();
		verticalLayout_1.addComponent(horizontalLayout_2);
		
		// label_1
		label_1 = new Label();
		label_1.setImmediate(false);
		label_1.setWidth("224px");
		label_1.setHeight("40px");
		label_1.setValue("Label");
		verticalLayout_1.addComponent(label_1);
		verticalLayout_1.setComponentAlignment(label_1, new Alignment(34));

		// horizontalLayout_1
		horizontalLayout_1 = buildHorizontalLayout_1();
		verticalLayout_1.addComponent(horizontalLayout_1);
		
		return verticalLayout_1;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayout_2() {
		// common part: create layout
		horizontalLayout_2 = new HorizontalLayout();
		horizontalLayout_2.setImmediate(false);
		horizontalLayout_2.setWidth("100.0%");
		horizontalLayout_2.setHeight("-1px");
		horizontalLayout_2.setMargin(false);
		horizontalLayout_2.setSpacing(true);
		
		// embedded_1
		embedded_1 = new Embedded();
		embedded_1.setImmediate(false);
		embedded_1.setWidth("-1px");
		embedded_1.setHeight("-1px");
		embedded_1
				.setSource(new ExternalResource(
						"http://www.gnurf.net/v3/wp-content/uploads/2008/03/012-pizza_01.thumbnail.png"));
		embedded_1.setType(1);
		embedded_1.setMimeType("image/png");
		horizontalLayout_2.addComponent(embedded_1);
		horizontalLayout_2.setComponentAlignment(embedded_1, new Alignment(33));
		
		// horizontalLayout_3
		horizontalLayout_3 = buildHorizontalLayout_3();
		horizontalLayout_2.addComponent(horizontalLayout_3);
		horizontalLayout_2.setComponentAlignment(horizontalLayout_3,
				new Alignment(34));
		
		return horizontalLayout_2;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayout_3() {
		// common part: create layout
		horizontalLayout_3 = new HorizontalLayout();
		horizontalLayout_3.setImmediate(false);
		horizontalLayout_3.setWidth("-1px");
		horizontalLayout_3.setHeight("-1px");
		horizontalLayout_3.setMargin(false);
		
		// homeButton
		homeButton = new Button();
		homeButton.setCaption("Button");
		homeButton.setImmediate(true);
		homeButton.setWidth("-1px");
		homeButton.setHeight("-1px");
		horizontalLayout_3.addComponent(homeButton);
		
		// customerButton
		customerButton = new Button();
		customerButton.setCaption("Button");
		customerButton.setImmediate(true);
		customerButton.setWidth("-1px");
		customerButton.setHeight("-1px");
		horizontalLayout_3.addComponent(customerButton);
		
		// checkoutButton
		checkoutButton = new Button();
		checkoutButton.setCaption("Button");
		checkoutButton.setImmediate(true);
		checkoutButton.setWidth("-1px");
		checkoutButton.setHeight("-1px");
		horizontalLayout_3.addComponent(checkoutButton);
		
		// logoutButton
		logoutButton = new Button();
		logoutButton.setCaption("Button");
		logoutButton.setImmediate(true);
		logoutButton.setWidth("-1px");
		logoutButton.setHeight("-1px");
		horizontalLayout_3.addComponent(logoutButton);
		
		// helpButton
		helpButton = new Button();
		helpButton.setCaption("Button");
		helpButton.setImmediate(true);
		helpButton.setWidth("-1px");
		helpButton.setHeight("-1px");
		horizontalLayout_3.addComponent(helpButton);
		
		// dynButton
		bmiButton = new Button();
		bmiButton.setCaption("bmi");
		bmiButton.setImmediate(false);
		bmiButton.setWidth("-1px");
		bmiButton.setHeight("-1px");
		horizontalLayout_3.addComponent(bmiButton);
		
		
		return horizontalLayout_3;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayout_1() {
		// common part: create layout
		horizontalLayout_1 = new HorizontalLayout();
		horizontalLayout_1.setImmediate(false);
		horizontalLayout_1.setWidth("-1px");
		horizontalLayout_1.setHeight("-1px");
		horizontalLayout_1.setMargin(false);
		
		// productcatalogue
		productcatalogue = new Tree();
		productcatalogue.setImmediate(false);
		productcatalogue.setWidth("200px");
		productcatalogue.setHeight("-1px");
		horizontalLayout_1.addComponent(productcatalogue);
		
		// verticalLayout_3
		verticalLayout_3 = buildVerticalLayout_3();
		horizontalLayout_1.addComponent(verticalLayout_3);
		
		return horizontalLayout_1;
	}

	@AutoGenerated
	private VerticalLayout buildVerticalLayout_3() {
		// common part: create layout
		verticalLayout_3 = new VerticalLayout();
		verticalLayout_3.setImmediate(false);
		verticalLayout_3.setWidth("-1px");
		verticalLayout_3.setHeight("-1px");
		verticalLayout_3.setMargin(false);
		
		// homeLayout_1
		homeLayout_1 = new HomeLayout();
		homeLayout_1.setImmediate(false);
		homeLayout_1.setWidth("-1px");
		homeLayout_1.setHeight("-1px");
		verticalLayout_3.addComponent(homeLayout_1);
		verticalLayout_3.setComponentAlignment(homeLayout_1, new Alignment(6));
		
		// productLayout_1
		productLayout_1 = new ProductLayout(m_maduraSessionManager);
		productLayout_1.setEnabled(false);
		productLayout_1.setImmediate(false);
		productLayout_1.setVisible(false);
		productLayout_1.setWidth("-1px");
		productLayout_1.setHeight("-1px");
		verticalLayout_3.addComponent(productLayout_1);
		verticalLayout_3.setComponentAlignment(productLayout_1,
				new Alignment(6));
		
		// shoppingCartLayout_1
		shoppingCartLayout_1 = new ShoppingCartLayout(m_maduraSessionManager);
		shoppingCartLayout_1.setEnabled(false);
		shoppingCartLayout_1.setImmediate(false);
		shoppingCartLayout_1.setVisible(false);
		shoppingCartLayout_1.setWidth("-1px");
		shoppingCartLayout_1.setHeight("-1px");
		verticalLayout_3.addComponent(shoppingCartLayout_1);
		
		// customerLayout_1
		customerLayout_1 = new CustomerLayout();
		customerLayout_1.setEnabled(false);
		customerLayout_1.setImmediate(false);
		customerLayout_1.setVisible(false);
		customerLayout_1.setWidth("-1px");
		customerLayout_1.setHeight("-1px");
		verticalLayout_3.addComponent(customerLayout_1);
		
		return verticalLayout_3;
	}

	public RulesPlugin getRulesPlugin() {
		return m_rulesPlugin;
	}

	public void setRulesPlugin(RulesPlugin rulesPlugin) {
		m_rulesPlugin = rulesPlugin;
	}

	public ViewManager getViewManager() {
		return m_viewManager;
	}

	public void setViewManager(ViewManager viewManager) {
		m_viewManager = viewManager;
	}

}
